#ifndef OCL_QUEUE_INCLUDED
#define OCL_QUEUE_INCLUDED 1

#include "../ocl/kernel.h"

typedef struct
{
	cl_command_queue            handle;     /*!< the queue           */
	cl_device_id                DEVICE;     /*!< CL_QUEUE_DEVICE     */
	cl_command_queue_properties PROPERTIES; /*!< CL_QUEUE_PROPERTIES */
} ocl_queue;

#define OCL_QUEUE_INIT { NULL, NULL, 0 }

int  ocl_queue_load( ocl_queue *q, const ocl_context *context, cl_device_id device_id,  cl_command_queue_properties pp );
void ocl_queue_quit( ocl_queue *q );

#define OCL_EVENTS_DECL  cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event
#define OCL_EVENTS_IMPL  num_events_in_wait_list,event_wait_list,event
#define OCL_NO_WAIT_LIST 0,NULL
#define OCL_NO_EVENTS    OCL_NO_WAIT_LIST, NULL

int ocl_enqueue_task( ocl_queue *q, ocl_kernel *kernel, OCL_EVENTS_DECL );
int ocl_enqueue_barrier( ocl_queue *q );
int ocl_flush(  ocl_queue *q );
int ocl_finish( ocl_queue *q );



int ocl_enqueue_read_buffer(ocl_queue  *q,
							ocl_buffer *buffer,
							cl_bool     blocking_read,
							size_t      offset,
							size_t      cb,
							void       *ptr, 
							OCL_EVENTS_DECL );

int ocl_enqueue_write_buffer(ocl_queue  *q,
							 ocl_buffer *buffer,
							 cl_bool     blocking_read,
							 size_t      offset,
							 size_t      cb,
							 const void *ptr, 
							 OCL_EVENTS_DECL );

int ocl_enqueue_ndrange_kernel(ocl_queue    *q,
							   ocl_kernel   *kernel,
							   cl_uint       work_dim,
							   const size_t *global_work_offset,
							   const size_t *global_work_size,
							   const size_t *local_work_size,
							   OCL_EVENTS_DECL );



#endif
